//
//  UIView+Expand.m
//  Pension
//
//  Created by gavin on 2020/5/20.
//  Copyright © 2020 XLH. All rights reserved.
//

#import "UIView+MJUI.h"

@implementation UIView (IB)

@dynamic mj_cornerRadius;
- (void)setMj_cornerRadius:(CGFloat)mj_cornerRadius {
    [self mj_cornerRadius:mj_cornerRadius];
}
@dynamic mj_borderWidth;
- (void)setMj_borderWidth:(CGFloat)mj_borderWidth{
    self.layer.borderWidth = mj_borderWidth;
}
@dynamic mj_borderColorName;
- (void)setMj_borderColorName:(NSString *)mj_borderColorName {
    self.layer.borderColor = [UIColor mj_colorName:mj_borderColorName].CGColor;
}
@dynamic mj_backgroundColorName;
- (void)setMj_backgroundColorName:(NSString *)mj_backgroundColorName {
    self.backgroundColor = [UIColor mj_colorName:mj_backgroundColorName];
}


@end

#pragma mark  Frame
@implementation UIView (Frame)

- (CGFloat)mj_top
{
    return self.frame.origin.y;
}
- (void)setMj_top:(CGFloat)sc_top
{
    CGRect frame = self.frame;
    frame.origin.y = sc_top;
    self.frame = frame;
}

- (CGFloat)mj_right
{
    return self.frame.origin.x + self.frame.size.width;
}

- (void)setMj_right:(CGFloat)sc_right
{
    CGRect frame = self.frame;
    frame.origin.x = sc_right - self.frame.size.width;
    self.frame = frame;
}

- (CGFloat)mj_bottom
{
    return self.frame.origin.y + self.frame.size.height;
}

- (void)setMj_bottom:(CGFloat)sc_bottom
{
    CGRect frame = self.frame;
    frame.origin.y = sc_bottom - self.frame.size.height;
    self.frame = frame;
}


- (CGFloat)mj_left
{
    return self.frame.origin.x;
}

- (void)setMj_left:(CGFloat)sc_left
{
    CGRect frame = self.frame;
    frame.origin.x = sc_left;
    self.frame = frame;
}

- (CGFloat)mj_width
{
    return self.frame.size.width;
}

- (void)setMj_width:(CGFloat)sc_width
{
    CGRect frame = self.frame;
    frame.size.width = sc_width;
    self.frame = frame;
}

- (CGFloat)mj_height
{
    return self.frame.size.height;
}

- (void)setMj_height:(CGFloat)sc_height
{
    CGRect frame = self.frame;
    frame.size.height = sc_height;
    self.frame = frame;
}

- (CGPoint)mj_origin {
    return self.frame.origin;
}

- (void)setMj_origin:(CGPoint)sc_origin
{
    CGRect frame = self.frame;
    frame.origin = sc_origin;
    self.frame = frame;
}

- (CGSize)mj_size {
    return self.frame.size;
}

- (void)setMj_size:(CGSize)sc_size
{
    CGRect frame = self.frame;
    frame.size = sc_size;
    self.frame = frame;
}

- (CGFloat)mj_centerX {
    return self.center.x;
}

- (void)setMj_centerX:(CGFloat)sc_centerX
{
    self.center = CGPointMake(sc_centerX, self.center.y);
}

- (CGFloat)mj_centerY {
    return self.center.y;
}

- (void)setMj_centerY:(CGFloat)sc_centerY
{
    self.center = CGPointMake(self.center.x, sc_centerY);
}
@end

#pragma mark  UIView
@implementation UIView (MJUI)

+ (id)mj_loadNibWithOwner:(nullable id)owner {
    NSString *className = [self mj_className];

    return [NSBundle.mainBundle loadNibNamed:className owner:owner options:nil].lastObject;
}

+ (id)mj_nibInstantiateWithOwner:(nullable id)owner {
    NSString *className = [self mj_className];
    return [[UINib nibWithNibName:className bundle:nil] instantiateWithOwner:owner options:nil].firstObject;
}

- (UIViewController *)mj_viewController {
    for (UIView *next = [self superview]; next; next = [next superview]) {
        UIResponder *nextResponder = [next nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)nextResponder;
        }
    }
    return nil;
}

- (void)mj_dropShadowWithOffset:(CGSize)offset
                cornerRadius:(CGFloat)cornerRadius
                      radius:(CGFloat)radius
                       color:(UIColor *)color
                     opacity:(CGFloat)opacity
{
    
    //设置圆角
    self.layer.cornerRadius = cornerRadius;
    self.layer.masksToBounds = true;
    //设置阴影
    self.layer.shadowColor = color.CGColor;
    self.layer.shadowOffset = offset;
    self.layer.shadowOpacity = opacity;
    self.layer.shadowRadius = radius;
    self.clipsToBounds = false;//当它取值为 NO 时，不剪裁子视图
    

}


- (void)mj_dropShadowWithOffset:(CGSize)offset
                      radius:(CGFloat)radius
                       color:(UIColor *)color
                     opacity:(CGFloat)opacity
{
    // Creating shadow path for better performance
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, self.bounds);
    self.layer.shadowPath = path;
    CGPathCloseSubpath(path);
    CGPathRelease(path);
 
    self.layer.shadowColor = color.CGColor;
    self.layer.shadowOffset = offset;
    if(radius > 0){
        self.layer.shadowRadius = radius;
    }
    self.layer.shadowOpacity = opacity;
 
    // Default clipsToBounds is YES, will clip off the shadow, so we disable it.
    self.clipsToBounds = NO;
 
}
- (void)mj_borderColor:(UIColor *)color width:(CGFloat)width {
    [self.layer setBorderWidth:width];
    [self.layer setBorderColor:color.CGColor];
    /*****注释:锯齿*****/
    self.layer.allowsEdgeAntialiasing = YES;
}

- (void)mj_cornerRadius:(CGFloat)radius {
    [self.layer setMasksToBounds:YES];
    [self.layer setCornerRadius:radius];
}

/**
 *  给控件本身添加圆角，不是通过图片实现的。
 *
 *    @param corner       添加哪些圆角
 *    @param cornerRadius    圆角大小
 *    @param targetSize        目标大小，即控件的frame.size
 */
- (void)mj_corner:(UIRectCorner)corner cornerRadius:(CGFloat)cornerRadius size:(CGSize)targetSize {
  CGRect frame = CGRectMake(0, 0, targetSize.width, targetSize.height);
  UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:frame
                                             byRoundingCorners:corner
                                                   cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];
  CAShapeLayer *layer = [CAShapeLayer layer];
  layer.frame = frame;
  layer.path = path.CGPath;
  
  self.layer.mask = layer;
}

- (void)mj_corner:(UIRectCorner)corner cornerRadius:(CGFloat)cornerRadius {
  [self mj_corner:corner cornerRadius:cornerRadius size:self.bounds.size];
}

- (void)mj_corner:(UIRectCorner)corner sColor:(UIColor *)sColor offset:(CGSize)offset radius:(CGFloat)radius  sRadius:(CGFloat)sRadius opacity:(CGFloat)opacity bgColor:(UIColor *)bgColor{
//    //是否包含 圆角CALayer 先移除再添加
    BOOL isContain = false;
    if(self.layer.sublayers.count > 0){
        CALayer *firstLayer = self.layer.sublayers[0];
        if ([firstLayer.mask isKindOfClass:[CAShapeLayer class]]) {
            isContain = true;
        }
    }
    //包含先删除
    if(isContain){
        CALayer *first = (CALayer *)self.layer.sublayers[0];
        [first removeFromSuperlayer];
    }
    

    //任意圆角
    CALayer *cornerLayer = [CALayer layer];
    cornerLayer.frame = self.bounds;
    cornerLayer.backgroundColor = bgColor.CGColor;
    
    //添加阴影
    self.backgroundColor = nil;
    self.layer.shadowColor = sColor.CGColor;
    self.layer.masksToBounds = NO;
    self.layer.shadowOpacity = opacity;
    self.layer.shadowOffset = offset;
    self.layer.shadowRadius = sRadius;
    
    CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
                                           byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)].CGPath;
    CAShapeLayer *lay = [CAShapeLayer layer];
    lay.path = path;
    cornerLayer.mask = lay;
    
    [self.layer insertSublayer:cornerLayer atIndex:0];

    
}

- (void)mj_gradientLayerWithColors:(NSArray *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint locations:(NSArray<NSNumber *> *)locations {
    
    [self removeGradientLayer];
    
    CAGradientLayer *gradientLayer = [[CAGradientLayer alloc]init];
    gradientLayer.frame = self.bounds;
    gradientLayer.colors = colors; // 设置
    gradientLayer.startPoint = startPoint; //Z
    gradientLayer.endPoint = endPoint; //
    gradientLayer.locations = locations; //

    [self.layer insertSublayer:gradientLayer atIndex:0];
}

- (void)mj_gradientLayerWithColors:(NSArray *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint{
    [self removeGradientLayer];
    
    CAGradientLayer *gradientLayer = [[CAGradientLayer alloc]init];
    gradientLayer.frame = self.bounds;
    gradientLayer.colors = colors; // 设置
    gradientLayer.startPoint = startPoint; //Z
    gradientLayer.endPoint = endPoint; //

    [self.layer insertSublayer:gradientLayer atIndex:0];
}

- (void)removeGradientLayer{
    //是否包含 borderLayer 先移除再添加
    BOOL isContain = false;
    NSArray *sl = self.layer.sublayers;
    for (CALayer *layer in sl) {
        if ([layer isKindOfClass:[CAGradientLayer class]]) {
            isContain = true;
        }
    }
    //包含先删除
    if(isContain){
        CALayer *first = (CALayer *)self.layer.sublayers[0];
        [first removeFromSuperlayer];
    }
}

- (void)mj_rounderWithCorners:(UIRectCorner)corners radius:(CGFloat)radius lineWidth:(CGFloat)lineWidth lineColor:(UIColor *_Nullable )lineColor dash:(NSArray<NSNumber *>*_Nullable )lineDashPattern{
    
    
    //是否包含 borderLayer 先移除再添加
    BOOL isContain = false;
    if(self.layer.sublayers.count > 0){
        CALayer *firstLayer = self.layer.sublayers[0];
        if ([firstLayer isKindOfClass:[CAShapeLayer class]]) {
            isContain = true;
        }
    }
    //包含先删除
    if(isContain){
        CALayer *first = (CALayer *)self.layer.sublayers[0];
        [first removeFromSuperlayer];
    }
    
    ///解决masonry布局获取不了正确的frame
//    [self.superview layoutIfNeeded];
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius,radius)];
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;
    
    CAShapeLayer *borderLayer = [CAShapeLayer layer];
    borderLayer.lineWidth = lineWidth;
    borderLayer.strokeColor = lineColor.CGColor;
    borderLayer.fillColor = [UIColor clearColor].CGColor;
    if (lineDashPattern) {
        borderLayer.lineDashPattern = lineDashPattern;
        //borderLayer.lineCap = @"butt";
    }
    borderLayer.path = maskPath.CGPath;
    
    [self.layer insertSublayer:borderLayer atIndex:0];
    self.layer.mask = maskLayer;
}

//最顶层视图
+ (UIWindow *)mj_topWindow {
    
    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
    NSArray *windows = [UIApplication sharedApplication].windows;
    for (id windowView in windows) {
        NSString *viewName = NSStringFromClass([windowView class]);
        //键盘
        if ([@"UIRemoteKeyboardWindow" isEqualToString:viewName]) {
            window = windowView;
           break;
        }
    }
    if (!window) {
        window = [[UIApplication sharedApplication].windows objectAtIndex:0];
    }
    return window;
   
}

/////
static char TouchGestureTag;
- (void)mj_addTapActionWithBlock:(MJTouchGestureActionBlock)block {
    objc_setAssociatedObject(self, &TouchGestureTag, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
    UITapGestureRecognizer *  gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(mj_gesture:)];
        self.userInteractionEnabled = YES;
        [self addGestureRecognizer:gesture];
}
- (void)mj_gesture:(UITapGestureRecognizer*)gesture
{
    if (gesture.state == UIGestureRecognizerStateRecognized)
    {
        MJTouchGestureActionBlock blockAction = (MJTouchGestureActionBlock)objc_getAssociatedObject(self, &TouchGestureTag);
        if (blockAction)
        {
            blockAction();
        }
    }
  
}
//
- (UIView *)mj_copyView{
//    return [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:self]];

    return [NSKeyedUnarchiver unarchivedObjectOfClass:[UIView class] fromData:[NSKeyedArchiver archivedDataWithRootObject:self requiringSecureCoding:NO error:nil] error:nil];
}

//左右抖动
-(void)mj_shakeHor{

    CAKeyframeAnimation *shakeAnim = [CAKeyframeAnimation animation];

    shakeAnim.keyPath = @"transform.translation.x";

    shakeAnim.duration = 0.2;

    CGFloat delta = 5;

    shakeAnim.values = @[@0,@(-delta), @(delta), @0];

    shakeAnim.repeatCount = 2;

    [self.layer addAnimation:shakeAnim forKey:nil];

}
- (void)mj_cornerWithType:(MJCornerRadiusType)type cornerRadius:(CGFloat)cornerRadius {
    if(type == MJCornerRadiusTypeTop){
        [self mj_corner:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadius:cornerRadius];
    }
    if(type == MJCornerRadiusTypeBottom){
        [self mj_corner:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadius:cornerRadius];
    }
    if(type == MJCornerRadiusTypeLeft){
        [self mj_corner:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadius:cornerRadius];
    }
    if(type == MJCornerRadiusTypeRight){
        [self mj_corner:UIRectCornerBottomRight | UIRectCornerTopRight cornerRadius:cornerRadius];
    }
    if(type == MJCornerRadiusTypeRight){
        [self mj_corner:UIRectCornerBottomRight | UIRectCornerTopRight cornerRadius:cornerRadius];
    }
    if(type == MJCornerRadiusTypeTopLeftBottomRight){
        [self mj_corner:UIRectCornerTopLeft | UIRectCornerBottomRight cornerRadius:cornerRadius];
    }
    if(type == MJCornerRadiusTypeTopRightBottomLeft){
        [self mj_corner:UIRectCornerTopRight | UIRectCornerBottomLeft cornerRadius:cornerRadius];
    }
}

-(void)mj_removeAllSubviews {
    for (UIView * view in self.subviews) {
        [view removeFromSuperview];
    }
}


/**
 ** lineView:       需要绘制成虚线的view
 ** lineLength:     虚线的宽度
 ** lineSpacing:    虚线的间距
 ** lineColor:      虚线的颜色
 **/
- (void)mj_drawDashlineLength:(int)lineLength lineSpacing:(int)lineSpacing lineColor:(UIColor *)lineColor
{
   
//    //是否包含 borderLayer 先移除再添加
//    BOOL isContain = false;
//    if(self.layer.sublayers.count > 0){
//        CALayer *firstLayer = self.layer.sublayers[0];
//        if ([firstLayer isKindOfClass:[CAShapeLayer class]]) {
//            isContain = true;
//        }
//    }
//    //包含先删除
//    if(isContain){
//        CALayer *first = (CALayer *)self.layer.sublayers[0];
//        [first removeFromSuperlayer];
//    }
    
    
    UIView *lineView = self;
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    [shapeLayer setBounds:lineView.bounds];
    [shapeLayer setPosition:CGPointMake(CGRectGetWidth(lineView.frame) / 2, CGRectGetHeight(lineView.frame))];
    [shapeLayer setFillColor:[UIColor clearColor].CGColor];
    //  设置虚线颜色为blackColor
    [shapeLayer setStrokeColor:lineColor.CGColor];
    //  设置虚线宽度
    [shapeLayer setLineWidth:CGRectGetHeight(lineView.frame)];
    [shapeLayer setLineJoin:kCALineJoinRound];
    //  设置线宽，线间距
    [shapeLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:lineLength], [NSNumber numberWithInt:lineSpacing], nil]];
    //  设置路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL,CGRectGetWidth(lineView.frame), 0);
    [shapeLayer setPath:path];
    CGPathRelease(path);
    //  把绘制好的虚线添加上来
    [lineView.layer addSublayer:shapeLayer];
}

- (void)mj_clickAwaitWithTime:(CGFloat)awaitTime{
    self.userInteractionEnabled = NO;
    //主线程演示操作
    MJUIAfter_GCD(awaitTime, ^{
        self.userInteractionEnabled = YES;
    });
}

- (void)mj_contentsWithImageNamed:(NSString *)imageNamed{
    //用此方法能让图片高度随右边的文本高度自适应，UIView设置背景图片
    UIImage *image = [UIImage imageNamed:imageNamed];
    self.layer.contents = (id)image.CGImage;
}

- (void)mj_cornerRadiusWithTopLeft:(CGFloat)topLeft topRight:(CGFloat)topRight bottomLeft:(CGFloat)bottomLeft bottomRight:(CGFloat)bottomRight{

        CGFloat minX = CGRectGetMinX(self.bounds);

        CGFloat minY = CGRectGetMinY(self.bounds);

        CGFloat maxX = CGRectGetMaxX(self.bounds);

        CGFloat maxY = CGRectGetMaxY(self.bounds);



        CGFloat topLeftCenterX = minX + topLeft;

        CGFloat topLeftCenterY = minY + topLeft;

        CGFloat topRightCenterX = maxX - topRight;

        CGFloat topRightCenterY = minY + topRight;

        CGFloat bottomLeftCenterX = minX + bottomLeft;

        CGFloat bottomLeftCenterY = maxY - bottomLeft;

        CGFloat bottomRightCenterX = maxX - bottomRight;

        CGFloat bottomRightCenterY = maxY - bottomRight;



        UIBezierPath *path = [UIBezierPath bezierPath];

        [path addArcWithCenter:CGPointMake(topLeftCenterX, topLeftCenterY) radius:topLeft startAngle:M_PI endAngle:3 * M_PI / 2.0 clockwise:YES];

        [path addArcWithCenter:CGPointMake(topRightCenterX, topRightCenterY)radius:topRight startAngle:3*M_PI/2.0 endAngle:0 clockwise:YES];

        [path addArcWithCenter:CGPointMake(bottomRightCenterX, bottomRightCenterY)radius:bottomRight startAngle:0 endAngle:M_PI_2 clockwise:YES];

        [path addArcWithCenter:CGPointMake(bottomLeftCenterX, bottomLeftCenterY)radius:bottomLeft startAngle:M_PI_2 endAngle:M_PI clockwise:YES];

        CAShapeLayer *masklayer = [[CAShapeLayer alloc]init];

        masklayer.frame=self.bounds;

        masklayer.path= path.CGPath;

        self.layer.mask= masklayer;

}
@end






#pragma mark ******************** UICollectionView
@implementation UICollectionView (Extend)

- (void)registerNibCell:(Class)cls {
    NSString *clsName = [cls mj_className];
    UINib *nib = [UINib nibWithNibName:clsName bundle:nil];
    [self registerNib:nib forCellWithReuseIdentifier:clsName];
}

@end

#pragma mark ******************** UICollectionViewCell
@implementation UICollectionViewCell (Extend)

+ (void)registerNibWithCollectionView:(UICollectionView *)collectionView {
    [collectionView registerNibCell:self.class];
}

+ (__kindof UICollectionViewCell *)reuseForCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath {
    return [collectionView dequeueReusableCellWithReuseIdentifier:[self mj_className] forIndexPath:indexPath];
}

@end


#pragma mark ******************** UICollectionReusableView

@implementation UICollectionReusableView (Extend)

+ (void)registerHeaderNibWithCollectionView:(UICollectionView *)collectionView{
    NSString *clsName = [self mj_className];
    UINib *nib = [UINib nibWithNibName:clsName bundle:nil];
    [collectionView registerNib:nib forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:clsName];
}

+ (nullable __kindof UICollectionReusableView *)reuseHeaderForCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath {
    return [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:[self mj_className] forIndexPath:indexPath];
}

+ (void)registerFooterNibWithCollectionView:(UICollectionView *)collectionView{
    NSString *clsName = [self mj_className];
    UINib *nib = [UINib nibWithNibName:clsName bundle:nil];
    [collectionView registerNib:nib forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:clsName];
}
+ (nullable __kindof UICollectionReusableView *)reuseFooterForCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath{
    return [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:[self mj_className] forIndexPath:indexPath];
}

@end





#pragma mark ******************** UITableView
@implementation UITableView (Extend)

- (void)registerNibCell:(Class)cls {
    NSString *clsName = [cls mj_className];
    UINib *nib = [UINib nibWithNibName:clsName bundle:nil];
    [self registerNib:nib forCellReuseIdentifier:clsName];
}

- (void)registerNibHeadFoot:(Class)cls {
    NSString *clsName = [cls mj_className];
    UINib *nib = [UINib nibWithNibName:clsName bundle:nil];
    [self registerNib:nib forHeaderFooterViewReuseIdentifier:clsName];
}

@end



#pragma mark ******************** UITableViewCell
@implementation UITableViewCell (Extend)

+ (void)registerNibWithTableView:(UITableView *)tableView {
    [tableView registerNibCell:self.class];
}

+ (__kindof UITableViewCell *)reuseForTableView:(UITableView *)tableView forIndexPath:(NSIndexPath *)indexPath {
    return [tableView dequeueReusableCellWithIdentifier:[self mj_className] forIndexPath:indexPath];
}

@end


#pragma mark ******************** UITableViewHeaderFooterView

@implementation UITableViewHeaderFooterView (Extend)

+ (void)registerNibWithTableView:(UITableView *)tableView{
    NSString *clsName = [self mj_className];
    UINib *nib = [UINib nibWithNibName:clsName bundle:nil];
    [tableView registerNib:nib forHeaderFooterViewReuseIdentifier:clsName];
}

+ (nullable __kindof UITableViewHeaderFooterView *)reuseForTableView:(UITableView *)tableView {
    return [tableView dequeueReusableHeaderFooterViewWithIdentifier:[self mj_className]];
}

@end
